home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / audio / drive / Straight.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  3.8 KB  |  158 lines

  1. /*
  2.  * Copyright 1992-1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. //////////////////////////////////////////////////////////////////////
  18. // Straight.c++ - definition of the straight class
  19. //
  20. // This class defines a straightaway stretch of road. It is
  21. // derived from the stretch abstract base class.
  22. //////////////////////////////////////////////////////////////////////
  23.  
  24. #include <math.h>
  25. #include "Stretch.h"
  26. #include "Straight.h"
  27.  
  28. Straight::Straight(
  29.     Stretch *prev, Stretch *next, 
  30.     float length, float width, float hill_angle,
  31.     float bank_angle, float loop_offset)
  32.     : Stretch(prev, next)
  33. {
  34.     _turn_angle = 0.0; // straights do not curve
  35.     
  36.     // specified in degrees, stored as radians
  37.     _hill_angle = hill_angle*M_PI/180.0;
  38.     _bank_angle = bank_angle*M_PI/180.0;
  39.  
  40.     _length = length;
  41.     _width = width;
  42.  
  43.     if (loop_offset == 0.0)
  44.     {
  45.         _type = STRAIGHT;
  46.         _step = 30.0; 
  47.     }
  48.     else
  49.     {
  50.         _type = LOOP;
  51.         _step = 15.0;
  52.     }
  53.     
  54.     // compute radius of the hill, if it's not flat
  55.     if (_hill_angle != 0.0)
  56.         _hill_radius = _length/_hill_angle;
  57.  
  58.     Stretch::compute_step();
  59.     Stretch::allocate_data();
  60.     
  61.     // find the accumulated offset and orientation 
  62.     SbVec3f prev_offset;
  63.     SbRotation prev_orientation;
  64.     Stretch::find_previous(prev_offset, prev_orientation);
  65.  
  66.     make_straight(prev_offset,prev_orientation, loop_offset);
  67.  
  68.     // match up ends
  69.     Stretch::match_ends();
  70.     
  71.     Stretch::init_scenery();
  72. }
  73.  
  74.  
  75. Straight::~Straight()
  76. {
  77. }
  78.  
  79.  
  80. void Straight::make_straight(SbVec3f prev_offset, 
  81.     SbRotation prev_orientation, float loop_offset)
  82. {
  83.     SbVec3f left, middle, right;
  84.  
  85.     // set initial values for x coordinates
  86.     left.setValue(- _width/2.0,0.0,0.0);
  87.     middle.setValue(0.0,0.0,0.0);
  88.     right.setValue(_width/2.0,0.0,0.0);
  89.  
  90.     // compute the 'center' of the hill
  91.     // use later to find the normals
  92.     SbVec3f center(middle[0],_hill_radius,0.0);
  93.  
  94.     float bank_step = _bank_angle/(_length/_step);
  95.     float bank = 0.0;
  96.  
  97.     float z = 0.0;
  98.  
  99.     for (int i = 0; i < _num_markers; i++)
  100.     {
  101.         
  102.         if (_hill_angle == 0.0)
  103.         {
  104.             // straight is flat
  105.             left[1] = middle[1] = right[1] = 0.0;
  106.             left[2] = middle[2] = right[2] = -z;
  107.             
  108.             _data[i].normal.setValue(0.0,1.0,0.0);
  109.         
  110.         }
  111.         else
  112.         {
  113.             // straight is a hill
  114.             left[1] = middle[1] = right[1] =
  115.                 _hill_radius * (1.0 - fcos(_hill_angle * z/_length));
  116.             
  117.             left[2] = middle[2] = right[2] = 
  118.                 - _hill_radius * fsin(_hill_angle * z/_length);
  119.  
  120.             // Compute the normal
  121.             _data[i].normal = center - middle;
  122.             _data[i].normal.normalize();
  123.             
  124.             if (_hill_radius < 0.0)
  125.             {
  126.                 // XXX Do X as well ?
  127.                 
  128.                 _data[i].normal[1] *= -1.0;
  129.                 _data[i].normal[2] *= -1.0;
  130.             }
  131.         }
  132.  
  133.          _data[i].left = left;
  134.         _data[i].middle = middle;
  135.         _data[i].right = right;
  136.  
  137.         float partial_loop_offset = 
  138.             loop_offset*(float)i/(float)(_num_markers - 1);
  139.  
  140.          _data[i].left[0] += partial_loop_offset;
  141.          _data[i].middle[0] += partial_loop_offset;
  142.          _data[i].right[0] += partial_loop_offset;
  143.  
  144.         // rotate the data and the normals about the center
  145.         // of the road by bank radians counter clockwise
  146.         Stretch::rotate_bank(i,bank);
  147.         bank += bank_step;
  148.  
  149.         z += _step;
  150.     }
  151.  
  152.     SbRotation this_quat(_data[0].normal,_data[_num_markers - 1].normal);
  153.     _orientation = this_quat * prev_orientation;
  154.  
  155.     Stretch::transform_data(prev_offset, prev_orientation);
  156. }
  157.  
  158.